package com.haixiaoke.saas.order.state.role;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.haixiaoke.saas.common.constant.LockConstants;
import com.haixiaoke.saas.common.constant.OrderConstants;
import com.haixiaoke.saas.common.enums.OrderStateEnum;
import com.haixiaoke.saas.common.enums.OrderTabEnum;
import com.haixiaoke.saas.common.exception.ServiceException;
import com.haixiaoke.saas.common.utils.DateUtils;
import com.haixiaoke.saas.common.utils.bean.BeanUtils;
import com.haixiaoke.saas.house.domain.House;
import com.haixiaoke.saas.lock.domain.HouseLock;
import com.haixiaoke.saas.lock.domain.LockFace;
import com.haixiaoke.saas.order.domain.Order;
import com.haixiaoke.saas.order.domain.OrderAuditRecord;
import com.haixiaoke.saas.order.domain.OrderLessee;
import com.haixiaoke.saas.order.state.server.IOrderStateServerRole;
import com.haixiaoke.saas.system.domain.LoginUser;
import com.haixiaoke.saas.system.framework.security.util.SecurityUtils;
import org.apache.commons.lang3.RandomUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

import static com.haixiaoke.saas.system.framework.security.util.SecurityUtils.getLoginUser;

/**
 * 已签约状态服务方实现类
 *
 * @author qixi
 */
public class SignedOrderOrderStateServerRole extends AbstractSpecificOrderOrderStateServerRole {
    private static final Logger LOG = LoggerFactory.getLogger(SignedOrderOrderStateServerRole.class);

    public SignedOrderOrderStateServerRole(IOrderStateServerRole stateServerRole) {
        super(stateServerRole);
    }

    @Override
    @Transactional
    public void cancel(Order order) {
        if (order.getCheckInTime().getTime() <= DateUtil.date().getTime()) {
            throw new ServiceException("租客已入住，不能作废订单");
        }

        String orderId = order.getOrderId();
        houseMemberService.rentingTerminationByOrderId(orderId);
        orderLesseeService.rentingTerminationByOrderId(orderId);

        addOrderStateRecord(order.getOrderId(), order.getOrderState(), OrderStateEnum.ORDER_STATE_CANCEL.getValue());
        order.setOrderState(OrderStateEnum.ORDER_STATE_CANCEL.getValue());
        order.setOrderTab(OrderTabEnum.ORDER_TAB_FAILURE.getValue());
        orderService.updateOrder(order);
    }

    @Override
    @Transactional
    public void refundRent(Order order) {
        String orderId = order.getOrderId();
        houseMemberService.rentingTerminationByOrderId(orderId);
        orderLesseeService.rentingTerminationByOrderId(orderId);

        addOrderStateRecord(order.getOrderId(), order.getOrderState(), OrderStateEnum.ORDER_STATE_REFUND_RENT.getValue(), OrderConstants.RECORD_SOURCE_ENTERPRISE, "正常退租", null);
        order.setOrderState(OrderStateEnum.ORDER_STATE_REFUND_RENT.getValue());
        order.setCheckOutApplicationTime(new Date());


        // 添加房管家人脸信息
        addHouseManager(order);


        orderService.updateOrder(order);
    }


    /**
     * 退租审核
     *
     * @param order
     */
    @Override
    @Transactional
    public void refundRentAudit(Order order) {
        addOrderStateRecord(order.getOrderId(), order.getOrderState(), OrderStateEnum.ORDER_STATE_REFUND_RENT_AUDIT.getValue());
        order.setOrderState(OrderStateEnum.ORDER_STATE_REFUND_RENT_AUDIT.getValue());

        LoginUser loginUser = SecurityUtils.getLoginUser();
        String tenantId = loginUser.getTenantId();
        OrderAuditRecord orderAuditRecord = new OrderAuditRecord();
        orderAuditRecord.setOrderContent(JSONUtil.toJsonStr(order));
        orderAuditRecord.setTenantId(tenantId);
        orderAuditRecord.setOrderId(order.getOrderId());
        orderAuditRecord.setAuditRecordType(OrderConstants.AUDIT_RECORD_TYPE_OUT);
        orderAuditRecord.setAuditRecordState(OrderConstants.AUDIT_RECORD_STATE_AUDIT);
        orderAuditRecord.setAddress(order.getPremisesAddress());

        // 获取承租者
        OrderLessee orderLessee = order.getOrderLessee();
        orderAuditRecord.setLodgerName(orderLessee.getLesseeName());
        orderAuditRecord.setLodgerPhone(orderLessee.getPhone());
        String username = loginUser.getUsername();
        orderAuditRecord.setCreateBy(username);
        orderAuditRecordService.insertOrderAuditRecord(orderAuditRecord);

        // order.setRealityCheckOutTime(null);
        order.setCheckOutApplicationTime(new Date());
        orderService.updateOrder(order);
    }

    @Override
    @Transactional
    public void relet(Order order) {
        Order newOrder = order.getOrder();

        String houseId = newOrder.getHouseId();
        House house = houseService.selectHouseById(houseId);
        BeanUtil.copyProperties(house, newOrder);
        String estateName = house.getEstateName();
        String buildingName = house.getBuildingName();
        newOrder.setPremisesAddress(estateName + buildingName + "栋" + house.getUnitName() + "单元" + house.getRoomNumber() + "房");

        BeanUtils.copyPropertiesIfNull(order, newOrder, "order");

        String orderId = "O" + System.currentTimeMillis() + RandomUtils.nextInt(10000, 100000);
        newOrder.setOrderId(orderId);
        newOrder.setOrderState(OrderStateEnum.ORDER_STATE_TO_BE_SIGNED.getValue());
        newOrder.setOrderTab(OrderTabEnum.ORDER_TAB_TO_BE_SIGNED.getValue());
        newOrder.setOrderType(Order.ORDER_TYPE_LONG_LEASE);
        newOrder.setLinkedOrderId(order.getOrderId());
        newOrder.setCreateTime(new Date());
        newOrder.setDeptId(getLoginUser().getDeptId());
        newOrder.setCreateBy(getLoginUser().getUsername());
        newOrder.setTradingMode(OrderConstants.TRADING_MODE_RELET);
        newOrder.setFinallySignTime(null);
        orderService.insertOrder(newOrder);

        order.setOrderState(OrderStateEnum.ORDER_STATE_SIGNED.getValue());
        orderService.updateOrder(order);

        OrderAuditRecord orderAuditRecord = orderAuditRecordService.selectOrderAuditRecordByOrderIdAndAuditRecordState(order.getOrderId(), OrderConstants.AUDIT_RECORD_STATE_AUDIT);
        if (ObjectUtil.isNotNull(orderAuditRecord)) {
            orderAuditRecord.setAfterOrderId(newOrder.getOrderId());
            orderAuditRecordService.updateOrderAuditRecord(orderAuditRecord);
        }
/*
        OrderLessee orderLessee = newOrder.getOrderLessee();
        orderLessee.setOrderId(newOrder.getOrderId());
        orderLessee.setHouseId(newOrder.getHouseId());
        orderLessee.setTenantId(newOrder.getTenantId());
        orderLessee.setLesseeState(OrderLessee.LESSEE_STATE_AFOOT);
        orderLesseeService.insertOrderLessee(orderLessee);

        List<HouseMember> houseMembers = houseMemberService.selectHouseMemberListByOrderId(order.getOrderId());

        boolean lesseeFlag = false;
        if (CollectionUtil.isNotEmpty(houseMembers)) {
            for (HouseMember x : houseMembers) {
                if (x.getMemberType().equals(HouseMember.MEMBER_TYPE_TENANTRY)) {
                    // 承租人非同一人
                    if (!orderLessee.getCardNumber().equals(x.getIdCard())) {
                        lesseeFlag = true;
                        continue;
                    }
                }
                HouseMember houseMember = new HouseMember();
                BeanUtil.copyProperties(x, houseMember);
                houseMember.setOrderId(newOrder.getOrderId());
                houseMember.setMemberId(null);
                houseMemberService.insertHouseMember(houseMember);
            }
        }

        // 新增承租人
        if (lesseeFlag) {
            HouseMember houseMember = new HouseMember();
            houseMember.setTenantId(newOrder.getTenantId());
            houseMember.setDeptId(newOrder.getDeptId());
            houseMember.setHouseId(newOrder.getHouseId());
            houseMember.setMemberType(HouseMember.MEMBER_TYPE_TENANTRY);
            houseMember.setMemberName(orderLessee.getLesseeName());
            houseMember.setMemberPhone(orderLessee.getPhone());
            houseMember.setIdCard(orderLessee.getCardNumber());
            houseMember.setIdCardImgs(orderLessee.getCardImgs());
            houseMember.setOrderId(newOrder.getOrderId());
            houseMemberService.insertHouseMember(houseMember);
        }*/

    }

    @Override
    @Transactional
    public void reletAudit(Order order) {
        addOrderStateRecord(order.getOrderId(), order.getOrderState(), OrderStateEnum.ORDER_STATE_RELET_AUDIT.getValue());
        order.setOrderState(OrderStateEnum.ORDER_STATE_RELET_AUDIT.getValue());

        LoginUser loginUser = SecurityUtils.getLoginUser();
        String tenantId = loginUser.getTenantId();
        OrderAuditRecord orderAuditRecord = new OrderAuditRecord();
        orderAuditRecord.setOrderContent(JSONUtil.toJsonStr(order));
        orderAuditRecord.setTenantId(tenantId);
        orderAuditRecord.setOrderId(order.getOrderId());
        orderAuditRecord.setAuditRecordType(OrderConstants.AUDIT_RECORD_TYPE_RELET);
        orderAuditRecord.setAuditRecordState(OrderConstants.AUDIT_RECORD_STATE_AUDIT);
        orderAuditRecord.setAddress(order.getPremisesAddress());

        // 获取承租者
        OrderLessee orderLessee = order.getOrderLessee();
        orderAuditRecord.setLodgerName(orderLessee.getLesseeName());
        orderAuditRecord.setLodgerPhone(orderLessee.getPhone());
        String username = loginUser.getUsername();
        orderAuditRecord.setCreateBy(username);
        orderAuditRecordService.insertOrderAuditRecord(orderAuditRecord);


        orderService.updateOrder(order);
    }

    @Override
    @Transactional
    public void exchangeHouseAudit(Order order) {
        addOrderStateRecord(order.getOrderId(), order.getOrderState(), OrderStateEnum.ORDER_STATE_CHANGE_ROOM_AUDIT.getValue());
        order.setOrderState(OrderStateEnum.ORDER_STATE_CHANGE_ROOM_AUDIT.getValue());

        LoginUser loginUser = SecurityUtils.getLoginUser();
        String tenantId = loginUser.getTenantId();
        OrderAuditRecord orderAuditRecord = new OrderAuditRecord();
        orderAuditRecord.setOrderContent(JSONUtil.toJsonStr(order));
        orderAuditRecord.setTenantId(tenantId);
        orderAuditRecord.setOrderId(order.getOrderId());
        orderAuditRecord.setAuditRecordType(OrderConstants.AUDIT_RECORD_TYPE_CHANGE);
        orderAuditRecord.setAuditRecordState(OrderConstants.AUDIT_RECORD_STATE_AUDIT);
        orderAuditRecord.setAddress(order.getPremisesAddress());

        // 获取承租者
        OrderLessee orderLessee = order.getOrderLessee();
        orderAuditRecord.setLodgerName(orderLessee.getLesseeName());
        orderAuditRecord.setLodgerPhone(orderLessee.getPhone());
        String username = loginUser.getUsername();
        orderAuditRecord.setCreateBy(username);
        orderAuditRecordService.insertOrderAuditRecord(orderAuditRecord);
        orderService.updateOrder(order);
    }

    /**
     * 换房
     *
     * @param order
     */
    @Override
    @Transactional
    public void exchangeHouse(Order order) {
        Order newOrder = order.getOrder();

        String houseId = newOrder.getHouseId();
        House house = houseService.selectHouseById(houseId);
        BeanUtil.copyProperties(house, newOrder);
        String estateName = house.getEstateName();
        String buildingName = house.getBuildingName();
        newOrder.setPremisesAddress(estateName + buildingName + "栋" + house.getUnitName() + "单元" + house.getRoomNumber() + "房");
        newOrder.setCreateTime(DateUtils.getNowDate());

        BeanUtils.copyPropertiesIfNull(order, newOrder, "order");

        String orderId = "O" + System.currentTimeMillis() + RandomUtils.nextInt(10000, 100000);
        newOrder.setOrderId(orderId);
        newOrder.setOrderState(OrderStateEnum.ORDER_STATE_TO_BE_SIGNED.getValue());
        newOrder.setOrderTab(OrderTabEnum.ORDER_TAB_TO_BE_SIGNED.getValue());
        newOrder.setOrderType(Order.ORDER_TYPE_LONG_LEASE);
        newOrder.setLinkedOrderId(order.getOrderId());
        newOrder.setDeptId(getLoginUser().getDeptId());
        newOrder.setCreateBy(getLoginUser().getUsername());
        newOrder.setTradingMode(OrderConstants.TRADING_MODE_CHANGE);

        newOrder.setFinallySignTime(null);
        orderService.insertOrder(newOrder);

        OrderAuditRecord orderAuditRecord = orderAuditRecordService.selectOrderAuditRecordByOrderId(order.getOrderId());
        if (ObjectUtil.isNotNull(orderAuditRecord)) {
            orderAuditRecord.setAfterOrderId(newOrder.getOrderId());
            orderAuditRecordService.updateOrderAuditRecord(orderAuditRecord);
        }


        addOrderStateRecord(order.getOrderId(), order.getOrderState(), OrderStateEnum.ORDER_STATE_REFUND_RENT.getValue(), OrderConstants.RECORD_SOURCE_ENTERPRISE, "换房退租", null);
        order.setOrderState(OrderStateEnum.ORDER_STATE_REFUND_RENT.getValue());
        order.setCheckOutApplicationTime(new Date());
        order.setRealityCheckOutTime(new Date());

        // 添加房管家人脸信息
        addHouseManager(order);

        orderService.updateOrder(order);
/*

        OrderLessee orderLessee = newOrder.getOrderLessee();
        orderLessee.setOrderId(newOrder.getOrderId());
        orderLessee.setHouseId(newOrder.getHouseId());
        orderLessee.setTenantId(newOrder.getTenantId());
        orderLessee.setLesseeState(OrderLessee.LESSEE_STATE_AFOOT);
        orderLesseeService.insertOrderLessee(orderLessee);

        List<HouseMember> houseMembers = houseMemberService.selectHouseMemberListByOrderId(order.getOrderId());

        boolean lesseeFlag = false;
        if (CollectionUtil.isNotEmpty(houseMembers)) {
            for (HouseMember x : houseMembers) {
                if (x.getMemberType().equals(HouseMember.MEMBER_TYPE_TENANTRY)) {
                    // 承租人非同一人
                    if (!orderLessee.getCardNumber().equals(x.getIdCard())) {
                        lesseeFlag = true;
                        continue;
                    }
                }
                HouseMember houseMember = new HouseMember();
                BeanUtil.copyProperties(x, houseMember);
                houseMember.setOrderId(newOrder.getOrderId());
                houseMember.setHouseId(newOrder.getHouseId());
                houseMember.setMemberId(null);
                houseMemberService.insertHouseMember(houseMember);
            }
        }

        // 新增承租人
        if (lesseeFlag) {
            HouseMember houseMember = new HouseMember();
            houseMember.setTenantId(newOrder.getTenantId());
            houseMember.setDeptId(newOrder.getDeptId());
            houseMember.setHouseId(newOrder.getHouseId());
            houseMember.setMemberType(HouseMember.MEMBER_TYPE_TENANTRY);
            houseMember.setMemberName(orderLessee.getLesseeName());
            houseMember.setMemberPhone(orderLessee.getPhone());
            houseMember.setIdCard(orderLessee.getCardNumber());
            houseMember.setIdCardImgs(orderLessee.getCardImgs());
            houseMember.setOrderId(newOrder.getOrderId());
            houseMemberService.insertHouseMember(houseMember);
        }
*/

    }

    private void addHouseManager(Order order) {
        List<LockFace> lockFaceList = lockFaceService.selectLockFaceListAndHouseIdAndUserTypeAndFaceState(order.getHouseId(), LockConstants.USER_TYPE_MANAGER, LockConstants.FACE_STATE_DISABLE);
        if (CollectionUtil.isNotEmpty(lockFaceList)) {
            for (LockFace lockFace : lockFaceList) {
                houseLockService.authorizationLockFace(lockFace.getMac(), lockFace);
            }
        }
        List<HouseLock> houseLockList = houseLockService.selectHouseLockByHouseIdAndLockState(order.getHouseId(), LockConstants.LOCK_STATE_FREEZE);
        if (CollectionUtil.isNotEmpty(houseLockList)) {
            houseLockService.updateHouseLockState(order.getHouseId(), houseLockList);
        }
    }


    /**
     * 转租
     */
    @Override
    @Transactional
    public void sublease(Order order) {
        Order newOrder = order.getOrder();
        String houseId = newOrder.getHouseId();
        House house = houseService.selectHouseById(houseId);
        BeanUtil.copyProperties(house, newOrder);
        String estateName = house.getEstateName();
        String buildingName = house.getBuildingName();
        newOrder.setPremisesAddress(estateName + buildingName + "栋" + house.getUnitName() + "单元" + house.getRoomNumber() + "房");

        BeanUtils.copyPropertiesIfNull(order, newOrder, "order");
        String orderId = "O" + System.currentTimeMillis() + RandomUtils.nextInt(10000, 100000);
        newOrder.setOrderId(orderId);
        newOrder.setOrderState(OrderStateEnum.ORDER_STATE_TO_BE_SIGNED.getValue());
        newOrder.setOrderTab(OrderTabEnum.ORDER_TAB_TO_BE_SIGNED.getValue());
        newOrder.setOrderType(Order.ORDER_TYPE_LONG_LEASE);
        newOrder.setLinkedOrderId(order.getOrderId());
        newOrder.setCreateTime(new Date());
        newOrder.setDeptId(getLoginUser().getDeptId());
        newOrder.setCreateBy(getLoginUser().getUsername());
        newOrder.setTradingMode(OrderConstants.TRADING_MODE_SUBLET);

        newOrder.setFinallySignTime(null);
     /*   // 转租后将预订人信息清空
        newOrder.setReserveUser(null);
        newOrder.setReserveUserPhone(null);*/
        newOrder.setReserveUserId(null);

        orderService.insertOrder(newOrder);

        addOrderStateRecord(order.getOrderId(), order.getOrderState(), OrderStateEnum.ORDER_STATE_REFUND_RENT.getValue(), OrderConstants.RECORD_SOURCE_ENTERPRISE, "换房退租", null);
        order.setOrderState(OrderStateEnum.ORDER_STATE_REFUND_RENT.getValue());
        order.setCheckOutApplicationTime(new Date());
        order.setRealityCheckOutTime(new Date());
        orderService.updateOrder(order);

        // 添加房管家人脸信息
        order.setHouseId(houseId);
        addHouseManager(order);

        OrderAuditRecord orderAuditRecord = orderAuditRecordService.selectOrderAuditRecordByOrderIdAndAuditRecordState(order.getOrderId(), OrderConstants.AUDIT_RECORD_STATE_AUDIT);
        if (ObjectUtil.isNotNull(orderAuditRecord)) {
            orderAuditRecord.setAfterOrderId(newOrder.getOrderId());
            orderAuditRecordService.updateOrderAuditRecord(orderAuditRecord);
        }
/*

        OrderLessee orderLessee = newOrder.getOrderLessee();
        orderLessee.setOrderId(newOrder.getOrderId());
        orderLessee.setHouseId(newOrder.getHouseId());
        orderLessee.setTenantId(newOrder.getTenantId());
        orderLessee.setLesseeState(OrderLessee.LESSEE_STATE_AFOOT);
        orderLesseeService.insertOrderLessee(orderLessee);

        String lesseeType = orderLessee.getLesseeType();
        if (OrderLessee.LESSEE_TYPE_PERSONAL.equals(lesseeType)) {
            HouseMember houseMember = new HouseMember();
            houseMember.setTenantId(newOrder.getTenantId());
            houseMember.setDeptId(newOrder.getDeptId());
            houseMember.setHouseId(newOrder.getHouseId());
            houseMember.setMemberType(HouseMember.MEMBER_TYPE_TENANTRY);
            houseMember.setMemberName(orderLessee.getLesseeName());
            houseMember.setMemberPhone(orderLessee.getPhone());
            houseMember.setIdCard(orderLessee.getCardNumber());
            houseMember.setIdCardImgs(orderLessee.getCardImgs());
            houseMember.setOrderId(newOrder.getOrderId());
            houseMemberService.insertHouseMember(houseMember);
        }*/
    }

    /**
     * 转租审核
     */
    @Override
    @Transactional
    public void subleaseAudit(Order order) {
        addOrderStateRecord(order.getOrderId(), order.getOrderState(), OrderStateEnum.ORDER_STATE_SUBLET_AUDIT.getValue());
        order.setOrderState(OrderStateEnum.ORDER_STATE_SUBLET_AUDIT.getValue());

        LoginUser loginUser = SecurityUtils.getLoginUser();
        String tenantId = loginUser.getTenantId();
        OrderAuditRecord orderAuditRecord = new OrderAuditRecord();
        orderAuditRecord.setOrderContent(JSONUtil.toJsonStr(order));
        orderAuditRecord.setTenantId(tenantId);
        orderAuditRecord.setOrderId(order.getOrderId());
        orderAuditRecord.setAuditRecordType(OrderConstants.AUDIT_RECORD_TYPE_SUBLET);
        orderAuditRecord.setAuditRecordState(OrderConstants.AUDIT_RECORD_STATE_AUDIT);
        orderAuditRecord.setAddress(order.getPremisesAddress());

        // 获取承租者
        OrderLessee orderLessee = order.getOrderLessee();
        orderAuditRecord.setLodgerName(orderLessee.getLesseeName());
        orderAuditRecord.setLodgerPhone(orderLessee.getPhone());
        String username = loginUser.getUsername();
        orderAuditRecord.setCreateBy(username);
        orderAuditRecordService.insertOrderAuditRecord(orderAuditRecord);
        orderService.updateOrder(order);
    }

    @Override
    @Transactional
    public void orderOvertime(Order order) {
        String orderId = order.getOrderId();
        houseMemberService.rentingTerminationByOrderId(orderId);
        orderLesseeService.rentingTerminationByOrderId(orderId);

        addOrderStateRecord(order.getOrderId(), order.getOrderState(), OrderStateEnum.ORDER_STATE_OVERTIME_REFUND_RENT.getValue());
        order.setOrderState(OrderStateEnum.ORDER_STATE_OVERTIME_REFUND_RENT.getValue());
        order.setOrderTab(OrderTabEnum.ORDER_TAB_OFF_LEASE.getValue());
        order.setRealityCheckOutTime(new Date());
        orderService.updateOrder(order);
    }

}
